<?php

namespace yunj\core\control\form\field;

use yunj\core\exception\GeneralException;

class Tree extends YunjField {

    // 操作项必要配置
    const ACTION_REQUIRE_ARGS = [
        'type' => '',                 // 触发事件类型（openTab 打开子页面、openPopup 打开弹出层页面、asyncEvent 异步事件）
        'event' => '',                // 事件名（type=asyncEvent将作为参数请求到后端）
        'title' => '',                // 标题
        'icon' => '',                 // 图标类名
        'url' => '',                  // 触发事件执行的url
        'confirmText' => '',          // 确认弹窗提示
        'auth' => '',                 // 操作项对应的权限key
    ];

    protected static function defineExtraArgs(): array {
        return [
            'mode' => 'checkbox',       // 模式（可选值：radio、checkbox、edit。默认checkbox）
            'nodes' => [],              // 节点（示例:[["id":1,"name":"xiaowang","pid":0,"nocheck":false,"checked":true,"chkDisabled":true],["id":2,"name":"xiaoli","pid":1]]）
            'nodeIdKey' => 'id',        // 节点唯一标识属性名称。默认为id
            'nodePidKey' => 'pid',      // 节点所属父节点唯一标识的属性名称。默认为pid
            'nodeNameKey' => 'name',    // 节点展示名称标识字段的属性名称。默认为name
            'retractLevel' => -1,       // 收起等级（默认-1不收起），从0开始取值
            'allOptional' => false,     // 所有可选（默认false），反之末级可选（仅对radio、checkbox模式有效）
            'dragSort' => false,        // 拖拽排序，true 任意排序，false 不能拖拽排序，level 同级排序（默认false，仅对edit模式有效）
            'options' => [],            // 操作项（仅对edit模式有效）
        ];
    }

    protected static function handleArgs(array $args): array {
        // nodes
        self::handleArgsByNodes($args);

        switch ($args["mode"]) {
            case "checkbox":
                if (!strstr($args["verify"], "arrayIn")) {
                    $args["verify"] .= ($args["verify"] ? "|" : "") . "arrayIn:" . implode(",", self::getArgsAllowNodeIds($args));
                }
                break;
            case "radio":
                if (!strstr($args["verify"], "in")) {
                    $args["verify"] .= ($args["verify"] ? "|" : "") . "in:" . implode(",", self::getArgsAllowNodeIds($args));
                }
                break;
        }
        // dragSort
        if (!is_bool($args['dragSort']) && $args['dragSort'] !== 'level') {
            throw new GeneralException('类型[tree]配置[dragSort]错误');
        }
        // options
        self::handleArgsByOptions($args);

        return $args;
    }

    // 处理节点
    protected static function handleArgsByNodes(array &$args): void {
        $nodes = $args['nodes'];
        if (!$nodes) {
            return;
        }
        $nodeIdKey = $args['nodeIdKey'];
        $nodePidKey = $args['nodePidKey'];
        if (in_array($args["mode"], ["checkbox", "radio"])) {
            // hasSub 是否有子节点
            foreach ($nodes as &$node) {
                $hasSub = false;
                foreach ($nodes as $otherNode) {
                    // 检查当前节点是否是其他节点的父节点
                    if ($otherNode[$nodePidKey] == $node[$nodeIdKey]) {
                        $hasSub = true;
                        break;
                    }
                }
                $node['hasSub'] = $hasSub;
            }
            // nocheck 是否不可选
            foreach ($nodes as &$node) {
                if (isset($node['nocheck'])) {
                    continue;
                }
                // 最后一级可选，则有子级则不可选
                $node['nocheck'] = !$args['allOptional'] && !!$node['hasSub'];
            }
        }
        $args['nodes'] = $nodes;
    }

    // 处理操作项参数
    protected static function handleArgsByOptions(array &$args): void {
        $options = $args['options'];
        if (!$options) {
            return;
        }
        $args['options'] = [];
        foreach ($options as $v) {
            if (is_string($v)) {
                $v = ['event' => $v];
            }
            if ($v['event'] === 'rename') {
                $v += [
                    'event' => 'rename',
                    'title' => '重命名',
                    'icon' => 'yunj-icon-rename',
                ];
            } elseif ($v['event'] === 'remove') {
                $v += [
                    'event' => 'remove',
                    'title' => '删除',
                    'icon' => 'yunj-icon-remove',
                ];
            }

            $option = array_supp($v, self::ACTION_REQUIRE_ARGS);
            // auth 权限判断
            if ($option['auth'] && !admin_member_auth_check($option['auth'])) {
                continue;
            }
            if (!$option['event']) {
                throw new GeneralException('类型[tree]配置[options][event]不能为空');
            }
            // 判断是否配置url
            if (in_array($option['type'], ['openTab', 'openPopup'])) {
                if (!$option['url']) {
                    throw new GeneralException('类型[tree]配置[options][type]=openTab或openPopup时，对应url不能为空');
                }
            }
            $args['options'][] = $option;
        }
    }

    // 获取允许的节点ids
    protected static function getArgsAllowNodeIds(array $args): array {
        $nodes = $args['nodes'];
        $nodeIdKey = $args['nodeIdKey'];
        $nodePidKey = $args['nodePidKey'];
        $allowNodeIds = [];
        foreach ($nodes as $node) {
            if (!($node["nocheck"] ?? false) && !($node['readonly'] ?? false)) {
                $allowNodeIds[] = $node[$nodeIdKey];
            }
        }
        return $allowNodeIds;
    }

}